/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frct_comm.h                                        */
/*  NOTE      = conntrack公用                                      */
/*  DATE      = 2014/10/28                                         */
/*******************************************************************/

#include <stdio.h>
#include <unistd.h>

#include "frct_comm.h"


/*******************************************************************************
*  FUNC     :  获取L7_transaction
*  ARGS     :  p_st_ct      (Conntrack *)
*  RTN      :  返回L7_transaction指针
*  NOTE     :  线程不安全
*******************************************************************************/
L7_transaction *frct_get_L7transaction(Conntrack *p_st_ct)
{
    Frlist_node *p_st_node = NULL;
    L7_analyzer *p_st_l7_analyzer=NULL;
    
    if(p_st_ct == NULL)
        return NULL;

    if(p_st_ct->i_active_l7proto_idx < 0)
        goto ERROR;

    if(  frlist_size(&p_st_ct->lst_hdr_l7proto) <  p_st_ct->i_active_l7proto_idx +1 )
        goto ERROR;

    p_st_node = frlist_node_idx(&p_st_ct->lst_hdr_l7proto, p_st_ct->i_active_l7proto_idx);
    if(p_st_node == NULL)
        return NULL;

    p_st_l7_analyzer = (L7_analyzer *)FRLIST_GET_NODE_DATA(p_st_node);
    if(p_st_l7_analyzer == NULL)
        return NULL;
    
    return p_st_l7_analyzer->p_st_transaction;
ERROR:
    return NULL;
}

/*******************************************************************************
*  FUNC     :  获取session
*  ARGS     :  p_st_ct      (Conntrack *)
*  RTN      :  返回session
*  NOTE     :  线程不安全
*******************************************************************************/
L7_session *frct_get_session(Conntrack *p_st_ct)
{
    Frlist_node *p_st_node = NULL;
    L7_analyzer *p_st_l7_analyzer=NULL;
    
    if(p_st_ct == NULL)
        return NULL;

    if(p_st_ct->i_active_l7proto_idx < 0)
        goto ERROR;

    if(  frlist_size(&p_st_ct->lst_hdr_l7proto) <  p_st_ct->i_active_l7proto_idx +1 )
        goto ERROR;

    p_st_node = frlist_node_idx(&p_st_ct->lst_hdr_l7proto, p_st_ct->i_active_l7proto_idx);
    if(p_st_node == NULL)
        return NULL;

    p_st_l7_analyzer = (L7_analyzer *)FRLIST_GET_NODE_DATA(p_st_node);
    if(p_st_l7_analyzer == NULL)
        return NULL;
    
    return p_st_l7_analyzer->p_st_session;
ERROR:
    return NULL;
}

/*******************************************************************************
*  FUNC     :  获取session中保存的用户名
*  ARGS     :  p_st_session      (L7_session *)
*  RTN      :  返回session中的用户名
*  NOTE     :  线程不安全
*******************************************************************************/
char *frct_get_session_username(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return p_st_session->p_username;
}

/*******************************************************************************
*  FUNC     :  设定session中的用户名
*  ARGS     :  p_st_session      (L7_session *)
*           :  p_username        (用户名)
*  RTN      :  FR_SUCC:成功, FR_FAIL:失败
*  NOTE     :  线程不安全,函数内部重新生成内存
*******************************************************************************/
int frct_set_session_username(L7_session *p_st_session, const char *p_username)
{
    char *p_name_tmp;
    if(p_st_session == NULL || p_username == NULL )
        return FR_FAIL;
    
    p_name_tmp = frstrdup(p_username);
    if(p_name_tmp == NULL)
        return FR_FAIL;
    
    if(p_st_session->p_username)
        frfree(p_st_session->p_username);
    
    p_st_session->p_username = p_name_tmp;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  释放session中的用户名
*  ARGS     :  p_st_session      (L7_session *)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void frct_free_session_username(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return;

    if(p_st_session->p_username)
    {
        frfree(p_st_session->p_username);
        p_st_session->p_username = NULL;
    }
    return;
}

/*******************************************************************************
*  FUNC     :  获取session中保存的starttime
*  ARGS     :  p_st_session      (L7_session *)
*  RTN      :  返回session中的starttime指针
*  NOTE     :  线程不安全
*******************************************************************************/
struct timeval *frct_get_session_starttime(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return &p_st_session->st_session_starttime;
}

/*******************************************************************************
*  FUNC     :  设定session中的starttime
*  ARGS     :  p_st_session      (L7_session *)
*           :  p_username        (用户名)
*  RTN      :  FR_SUCC:成功, FR_FAIL:失败
*  NOTE     :  线程不安全
*******************************************************************************/
int frct_set_session_starttime(L7_session *p_st_session, struct timeval *p_st_starttime)
{
    if(p_st_session == NULL || p_st_starttime == NULL )
        return FR_FAIL;
    
    p_st_session->st_session_starttime.tv_sec = p_st_starttime->tv_sec;
    p_st_session->st_session_starttime.tv_usec = p_st_starttime->tv_usec;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  获取session中保存的stoptime
*  ARGS     :  p_st_session      (L7_session *)
*  RTN      :  返回session中的stoptime指针
*  NOTE     :  线程不安全
*******************************************************************************/
struct timeval *frct_get_session_stoptime(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return &p_st_session->st_session_stoptime;
}

/*******************************************************************************
*  FUNC     :  设定session中的stoptime
*  ARGS     :  p_st_session      (L7_session *)
*           :  p_username        (用户名)
*  RTN      :  FR_SUCC:成功, FR_FAIL:失败
*  NOTE     :  线程不安全
*******************************************************************************/
int frct_set_session_stoptime(L7_session *p_st_session, struct timeval *p_st_stoptime)
{
    if(p_st_session == NULL || p_st_stoptime == NULL )
        return FR_FAIL;
    
    p_st_session->st_session_stoptime.tv_sec = p_st_stoptime->tv_sec;
    p_st_session->st_session_stoptime.tv_usec = p_st_stoptime->tv_usec;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  获取session中保存的private
*  ARGS     :  p_st_session      (L7_session *)
*  RTN      :  返回session中的private
*  NOTE     :  线程不安全
*******************************************************************************/
void *frct_get_session_private(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return p_st_session->p_session_private;
}

/*******************************************************************************
*  FUNC     :  设定session中的private
*  ARGS     :  p_st_session      (L7_session *)
*           :  p_session_private (void *)
*  RTN      :  0:成功, 1:失败, 2:p_session_private已经存在,设置失败
*  NOTE     :  线程不安全
*******************************************************************************/
int frct_set_session_private(L7_session *p_st_session, void *p_session_private)
{
    if(p_st_session == NULL || p_session_private == NULL )
        return 1;
    
    if(p_st_session->p_session_private)
        return 2;
    
    p_st_session->p_session_private = p_session_private;
    return 0;
}

/*******************************************************************************
*  FUNC     :  获取session中保存的status
*  ARGS     :  p_st_session      (L7_session *)
*  RTN      :  返回session中的status指针
*  NOTE     :  线程不安全
*******************************************************************************/
int *frct_get_session_status(L7_session *p_st_session)
{
    if(p_st_session == NULL)
        return NULL;

    return &p_st_session->i_status;
}

/*******************************************************************************
*  FUNC     :  设定session中的i_status
*  ARGS     :  p_st_session      (L7_session *)
*           :  i_status          (状态)
*  RTN      :  FR_SUCC:成功, FR_FAIL:失败
*  NOTE     :  线程不安全
*******************************************************************************/
int frct_set_session_status(L7_session *p_st_session, int i_status)
{
    if(p_st_session == NULL )
        return FR_FAIL;
    
    p_st_session->i_status = i_status;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  释放L7_session
*  ARGS     :  p_st_session      (L7_session *)
*  RTN      :  
*  NOTE     :  线程不安全
*******************************************************************************/
void frct_free_l7_session(L7_module *p_st_l7_module, L7_session *p_st_l7_session)
{
    if(p_st_l7_session == NULL)
        return;
    
    if(p_st_l7_session->p_username)
    {
        frfree(p_st_l7_session->p_username);
        p_st_l7_session->p_username = NULL;
    }
    
    if(p_st_l7_session->p_session_private )
    {
        if( p_st_l7_module && p_st_l7_module->session_destory)
        {
            p_st_l7_module->session_destory(p_st_l7_session->p_session_private);
        }
        p_st_l7_session->p_session_private = NULL;
    }
    
    return;
}

/*******************************************************************************
*  FUNC     :  释放L7_transaction
*  ARGS     :  p_st_l7_transaction      (L7_transaction *)
*  RTN      :  
*  NOTE     :  线程不安全
*******************************************************************************/
void frct_free_l7_transaction(L7_transaction *p_st_l7_transaction)
{
    if(p_st_l7_transaction == NULL)
        return;
    
    if(p_st_l7_transaction->p_transaction_code)
    {
        frfree(p_st_l7_transaction->p_transaction_code);
        p_st_l7_transaction->p_transaction_code = NULL;
    }
    
    if(p_st_l7_transaction->p_transaction_title)
    {
        frfree(p_st_l7_transaction->p_transaction_title);
        p_st_l7_transaction->p_transaction_title = NULL;
    }

    if(p_st_l7_transaction->p_response_codestring)
    {
        frfree(p_st_l7_transaction->p_response_codestring);
        p_st_l7_transaction->p_response_codestring = NULL;
    }
    
    return;
}



/*******************************************************************************
*  FUNC     :  判断是当前连接的服务端/客户端
*  ARGS     :  p_st_ct      (Conntrack *)
*           :  ui_ip        (ip)
*           :  us_port      (port)
*  RTN      :  FR_SRV_IP_PORT FR_CLIENT_IP_PORT FR_DIRECT_UNKNOWN
*  NOTE     :  
*******************************************************************************/
int frcap_get_cs_direction(Conntrack *p_st_ct, u_int ui_ip, u_short us_port)
{
    if(p_st_ct == NULL || p_st_ct->flg_ct_direct == FR_DIRECT_UNKNOWN)
        return FR_DIRECT_UNKNOWN;
    
    if(p_st_ct->dst_ip == ui_ip && p_st_ct->dst_port == us_port)
        return FR_SRV_IP_PORT;
    else if(p_st_ct->src_ip == ui_ip && p_st_ct->src_port == us_port)
        return FR_CLIENT_IP_PORT;
    else
        return FR_DIRECT_UNKNOWN;
}

/*******************************************************************************
*  FUNC     :  设置当前服务器的ip+port
*  ARGS     :  p_st_ct      (Conntrack *)
*           :  ui_ip        (ip)
*           :  us_port      (port)
*  RTN      :  FR_SUCC:成功, FR_FAIL:失败
*  NOTE     :  
*******************************************************************************/
int frcap_set_cs_srv(Conntrack *p_st_ct, u_int ui_ip, u_short us_port)
{
    char arr_mac[APM_MAC_SIZE];
    u_short us_tmp;
    u_int ui_tmp;
    
    if(p_st_ct == NULL)
        return FR_FAIL;
    
    if( !(p_st_ct->src_ip == ui_ip && p_st_ct->src_port == us_port)
        && !(p_st_ct->dst_ip == ui_ip && p_st_ct->dst_port == us_port) )
        return FR_FAIL;
    
    p_st_ct->flg_ct_direct = FR_DIRECT_KNOWN;
    if( p_st_ct->dst_ip == ui_ip && p_st_ct->dst_port == us_port)
        return FR_SUCC;
    
    memcpy(arr_mac, p_st_ct->src_mac, sizeof(arr_mac));
    memcpy(p_st_ct->src_mac, p_st_ct->dst_mac, sizeof(p_st_ct->src_mac));
    memcpy(p_st_ct->dst_mac, arr_mac, sizeof(p_st_ct->dst_mac));
    
    ui_tmp = p_st_ct->src_ip;
    p_st_ct->src_ip = p_st_ct->dst_ip;
    p_st_ct->dst_ip = ui_tmp;
    
    us_tmp = p_st_ct->src_port;
    p_st_ct->src_port = p_st_ct->dst_port;
    p_st_ct->dst_port = us_tmp;

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  获取当前使用的L7_analyzer
*  ARGS     :  p_st_ct       (Conntrack *)
*  RTN      :  L7_analyzer *
*  NOTE     :
*******************************************************************************/
L7_analyzer *frproto_l7_get_analyzer(Conntrack *p_st_ct)
{
    Frlist_node *p_st_l7_proto_node= NULL;
    L7_analyzer *p_st_l7_analyzer = NULL;

    if(p_st_ct == NULL)
        return NULL;

    p_st_l7_proto_node = frlist_node_idx( &p_st_ct->lst_hdr_l7proto, p_st_ct->i_active_l7proto_idx);
    if(p_st_l7_proto_node)
        p_st_l7_analyzer = (L7_analyzer *)FRLIST_GET_NODE_DATA(p_st_l7_proto_node);

    return p_st_l7_analyzer;
}

